using System;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.IO;
using System.Text;
using System.Collections;

namespace Widgetsphere.Core.Util
{
	public partial class SerializeHelper
	{
		public SerializeHelper()
		{
		}

		#region xmlserialize helpers
		public static void XMLSerialize(string fileName, object o)
		{
			XmlSerializer serializer = new XmlSerializer(o.GetType());
			using (TextWriter writer = new StreamWriter(fileName))
			{
				writer.Write(XMLSerialize(o));
			} 
		}

		public static object XMLDeserialize(string fileName, System.Type type)
		{
			using (TextReader reader = new StreamReader(fileName))
			{
				return XMLDeserializeFromString(reader.ReadToEnd(), type);
			}
		}

		public static string XMLSerialize(object o)
		{
			if(o.GetType() == typeof(Hashtable))
			{
				return XMLSerializeHashtable((Hashtable)o);
			}
			else
			{
				StringBuilder sb = new StringBuilder();
				XmlSerializer serializer = new XmlSerializer(o.GetType());
				using (StringWriter writer = new StringWriter(sb))
				{
					serializer.Serialize(writer, o);
				} 
				return sb.ToString();
			}
		}

		public static object XMLDeserializeFromString(string xml, System.Type type)
		{
			if(type == typeof(Hashtable))
			{
				return XMLDeserializeHashtable(xml);
			}
			else
			{
				using (StringReader reader = new StringReader(xml))
				{
					XmlSerializer serializer1 = new XmlSerializer(type);
					return serializer1.Deserialize(reader);
				}
			}
		}

		private static Hashtable XMLDeserializeHashtable(string xml)
		{
			Hashtable returnVal = new Hashtable();
			StringReader sReader = new StringReader(xml);
			XmlTextReader xReader = new XmlTextReader(sReader);

			try
			{
				xReader.ReadStartElement("HashtableAnyType");
				while(xReader.Read())
				{
					string key = xReader.ReadElementString("Key");
					string keyType = (string)XMLDeserializeFromString(xReader.ReadElementString("KeyType"), typeof(string));
					string val = xReader.ReadElementString("Value");
					string valueType = (string)XMLDeserializeFromString(xReader.ReadElementString("ValueType"), typeof(string));
					returnVal.Add(XMLDeserializeFromString(key, Type.GetType(keyType)), XMLDeserializeFromString(val, Type.GetType(valueType)));
					xReader.ReadEndElement();
				}
				
			}
			finally
			{
				xReader.Close();
			}
			return returnVal;
		}

		private static string XMLSerializeHashtable(Hashtable ht)
		{
			StringWriter sWriter = new StringWriter();
			XmlTextWriter xWriter = new XmlTextWriter(sWriter);
			try
			{		
				xWriter.WriteStartDocument();
				xWriter.WriteStartElement("HashtableAnyType");
				foreach(object key in ht.Keys)
				{
					xWriter.WriteStartElement("KeyValuePair");
					xWriter.WriteElementString("Key", XMLSerialize(key));
					xWriter.WriteElementString("KeyType", XMLSerialize(key.GetType().FullName));
					xWriter.WriteElementString("Value", XMLSerialize(ht[key]));
					xWriter.WriteElementString("ValueType", XMLSerialize(ht[key].GetType().FullName));
					xWriter.WriteEndElement();
				}
				xWriter.WriteEndElement();
				xWriter.WriteEndDocument();
			}
			finally
			{
				xWriter.Close();
			}
			return sWriter.ToString();

		}
		#endregion

		#region soapserialize helpers
		public static void SoapSerialize(string fileName, object o)
		{
			using (TextWriter writer = new StreamWriter(fileName))
			{
				writer.Write(SoapSerialize(o));
			} 
		}

		public static object SoapDeserialize(string fileName)
		{
			using (TextReader reader = new StreamReader(fileName))
			{
				return SoapDeserializeFromString(reader.ReadToEnd());
			}
		}

		public static string SoapSerialize(object o)
		{
			string returnVal = string.Empty;
			StringBuilder sb = new StringBuilder();
			SoapFormatter serializer = new SoapFormatter();
			using (MemoryStream ms = new MemoryStream())
			{
				serializer.Serialize(ms, o);
				returnVal = StringHelper.MemoryStreamToString(ms);		
			} 
			return returnVal;
		}

		public static object SoapDeserializeFromString(string soap)
		{
			try
			{
				using (MemoryStream ms = StringHelper.StringToMemoryStream(soap))
				{
					SoapFormatter serializer = new SoapFormatter();
					return serializer.Deserialize(ms);
				}
			}
			catch(Exception ex)
			{
				System.Diagnostics.Trace.WriteLine(ex.ToString());
				throw;
			}
		}
		#endregion


	}
}